package com.ecoolex.ying.space.admin.graphql;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.google.common.collect.Lists;
import com.alibaba.fastjson.JSONArray;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.BeanUtil;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.admin.AdminMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.annotation.AdminAuthoritativeRegister;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMember;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberManager;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.modularize.api.service.storage.process.ImageProcess;
import com.ecoolex.framework.modularize.api.service.storage.zoom.AdaptiveCenterCuttingZoom;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.ying.space.admin.core.AdminConstant;
import com.ecoolex.ying.space.entity.OutsourcingPackaged;
import com.ecoolex.ying.space.entity.WholeHouseCase;
import com.ecoolex.ying.space.entity.WholeHouseCase.Column;
import com.ecoolex.ying.space.entity.WholeHouseCaseItems;
import com.ecoolex.ying.space.pojo.AddWholeHouseCaseDTO;
import com.ecoolex.ying.space.pojo.AddWholeHouseCaseItemsDTO;
import com.ecoolex.ying.space.pojo.EditWholeHouseCaseDTO;
import com.ecoolex.ying.space.ws.OutsourcingGoodsService;
import com.ecoolex.ying.space.ws.WholeHouseCaseService;


@GraphQL2Module(type = Type.Admin, description = "整屋案例管理")
@AdminAuthoritativeRegister(parentKey = AdminConstant.AUTH_MODULE_KEY,
    key = WholeHouseCaseGraphql.AUTH,
    name = "整屋案例管理")
public class WholeHouseCaseGraphql {

    public static final String AUTH = AdminConstant.AUTH_MODULE_KEY + "-WHOLEHOUSECASE";

    @Autowired
    private StorageService storageService;

    @Autowired
    private WholeHouseCaseService wholeHouseCaseService;

    @Autowired
    private OutsourcingGoodsService outsourcingGoodsService;

    @Autowired
    private ConsumerMemberManager consumerMemberManager;

    @TypeField(type = WholeHouseCase.class, field = "isAssociatedWholeHouseCase", description = "是否关联")
    public boolean isAssociated(@Source WholeHouseCase source) {
        return wholeHouseCaseService.getMarktingWholeHouseCaseByCaseId(source.getCaseId()) == null ? false
            : true;
    }

    @TypeField(type = WholeHouseCase.class, field = "releaseUser", description = "发布用户")
    public ConsumerMember getCommentUser(@Source WholeHouseCase source) {
        return consumerMemberManager.getByUserId(source.getUserId());
    }

    @TypeField(type = WholeHouseCase.class, field = "coverImage", description = "案例封面")
    public StorageInfo coverImage(@Source WholeHouseCase source) {
        return storageService.get(source.getCoverImage());
    }

    @TypeField(type = WholeHouseCaseItems.class, field = "images", description = "案例栏目图片")
    public List<StorageInfo> images(@Source WholeHouseCaseItems source) {
        JSONArray array = JSONArray.parseArray(source.getImages());
        List<String> storageIdLsit = array.toJavaList(String.class);
        return storageIdLsit.stream().map(storageId -> storageService.get(storageId)).collect(Collectors.toList());
    }

    @TypeField(type = WholeHouseCase.class, field = "wholeHouseCaseItemsList", description = "案例栏目列表")
    public List<WholeHouseCaseItems> itemList(@Source WholeHouseCase source) {
        return wholeHouseCaseService.getWholeHouseCaseItemsByCaseId(source.getCaseId());
    }

    @TypeField(type = WholeHouseCaseItems.class, field = "outsourcingPackaged", description = "外购套餐")
    public OutsourcingPackaged outsourcingPackaged(@Source WholeHouseCaseItems source) {
        return outsourcingGoodsService.getOutsourcingPackagedById(source.getOutsourcingPackagedId());
    }

    @TypeField(type = WholeHouseCase.class, field = "canEdit", description = "能编辑")
    public boolean canEdit(@Source WholeHouseCase source) {
        return !source.getOnline();
    }

    @TypeField(type = WholeHouseCase.class, field = "canDel", description = "能删除")
    public boolean canDel(@Source WholeHouseCase source) {
        return !source.getOnline();
    }

    @TypeField(type = WholeHouseCase.class, field = "canOnline", description = "能上线")
    public boolean canOnline(@Source WholeHouseCase source) {
        return !source.getOnline();
    }

    @TypeField(type = WholeHouseCase.class, field = "canOffline", description = "能下线")
    public boolean canOffline(@Source WholeHouseCase source) {
        return source.getOnline();
    }

    private static final String AUTH_GET = AUTH + "-GET";

    @QueryField(field = "wholeHouseCase", description = "整屋案例详情")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_GET, name = "整屋案例详情")
    public WholeHouseCase get(@NonNull Integer caseId, AdminMemberAuthority user) {
        user.assertLogin();
        return wholeHouseCaseService.getWholeHouseCaseById(caseId);
    }

    private static final String AUTH_QUERY = AUTH + "-QUERY";

    @QueryField(field = "wholeHouseCaseList", description = "整屋案例列表")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_QUERY, name = "整屋案例列表")
    public Pagination<WholeHouseCase> query(Boolean online, String name, @NonNull Sorting[] sorts, @NonNull Page page, AdminMemberAuthority user) {
        user.assertLogin();
        return wholeHouseCaseService.queryWholeHouseCase(online, name, sorts, page);
    }

    @MutationField(field = "uploadCaseCoverImage", description = { "上传案例封面" })
    public StorageInfo uploadCoverImage(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("WholeHouseCase", "CoverImage");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());

        ImageProcess imageProcess = new ImageProcess();
        imageProcess.setSync(true);
        imageProcess.setKey("preview");
        imageProcess.setQuality(0.8F);
        imageProcess.setZoomMode(new AdaptiveCenterCuttingZoom(750, 375));
        return storageService.upload(request, uploadSource, uploadLimit, imageProcess);
    }

    @MutationField(field = "uploadItemImages", description = { "上传案例栏目图片" })
    public StorageInfo uploadImages(@NonNull Upload request, AdminMemberAuthority user) {
        if (!user.auth(AUTH_ADD) && !user.auth(AUTH_EDIT)) {
            user.notAuthority();
        }
        UploadSource uploadSource = new UploadSource("WholeHouseCase", "Images");
        UploadLimit uploadLimit = new UploadLimit();
        uploadLimit.setMaxSize(FileSize.MB.byteLength(10));
        uploadLimit.setAllowMimeType(MimeType.IMAGE.commons());
        return storageService.upload(request, uploadSource, uploadLimit);
    }

    private static final String AUTH_ADD = AUTH + "-ADD";

    @MutationField(field = "addWholeHouseCase", description = "添加整屋案例")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ADD, name = "添加整屋案例")
    public WholeHouseCase add(@NonNull AddWholeHouseCaseDTO record, @NonNull List<AddWholeHouseCaseItemsDTO> itemsDTOList, AdminMemberAuthority user) {
        user.assertAuth(AUTH_ADD);
        return wholeHouseCaseService.addWholeHouseCase(record,
            itemsDTOList.stream().collect(Collectors.toList()),
            user.userName());
    }

    private static final String AUTH_EDIT = AUTH + "-EDIT";

    @MutationField(field = "editWholeHouseCase", description = "编辑整屋案例")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_EDIT, name = "编辑整屋案例")
    public WholeHouseCase update(@NonNull EditWholeHouseCaseDTO record, @NonNull List<AddWholeHouseCaseItemsDTO> itemsDTOList, AdminMemberAuthority user) {
        user.assertAuth(AUTH_EDIT);
        WholeHouseCase old = wholeHouseCaseService.getWholeHouseCaseById(record.getCaseId());
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "案例不存在");

        BeanUtil.copy(record,
            old,
            Lists.newArrayList(Column.online, Column.deleted, Column.createUser, Column.createTime).stream().map(
                Column::getJavaProperty).toArray(String[]::new));
        return wholeHouseCaseService.editWholeHouseCase(old, itemsDTOList, user.userName());
    }

    private static final String AUTH_DEL = AUTH + "-DEL";

    @MutationField(field = "deleteWholeHouseCase", description = "删除整屋案例")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_DEL, name = "删除整屋案例")
    public boolean delete(@NonNull Integer caseId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_DEL);
        WholeHouseCase old = wholeHouseCaseService.getWholeHouseCaseById(caseId);
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "案例不存在");
        wholeHouseCaseService.deleteWholeHouseCase(old, user.userName());
        return true;
    }

    private static final String AUTH_ONLINE = AUTH + "-ONLINE";

    @MutationField(field = "onlineWholeHouseCase", description = "上线整屋案例")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_ONLINE, name = "上线整屋案例")
    public boolean online(@NonNull Integer caseId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_ONLINE);
        WholeHouseCase old = wholeHouseCaseService.getWholeHouseCaseById(caseId);
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "案例不存在");
        wholeHouseCaseService.onlineWholeHouseCase(old, user.userName());
        return true;
    }

    private static final String AUTH_OFFLINE = AUTH + "-OFFLINE";

    @MutationField(field = "offlineWholeHouseCase", description = "下线整屋案例")
    @AdminAuthoritativeRegister(parentKey = AUTH, key = AUTH_OFFLINE, name = "下线整屋案例")
    public boolean offline(@NonNull Integer caseId, AdminMemberAuthority user) {
        user.assertAuth(AUTH_OFFLINE);
        WholeHouseCase old = wholeHouseCaseService.getWholeHouseCaseById(caseId);
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "案例不存在");
        wholeHouseCaseService.offlineWholeHouseCase(old, user.userName());
        return true;
    }

}
